package plugins.AI;

import kd.bos.form.gpt.IGPTAction;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * GetQingHtmlAction类实现了IGPTAction接口，用于处理特定的动作（如GET_QING_HTML），并将HTML内容保存为文件。
 */
public class GetQingHtmlAction implements IGPTAction {

    // 定义常量
    private static final String DIRECTORY_PATH = "isv/gptQing"; // 目标目录路径
    private static final String FILE_EXTENSION = ".html"; // 文件扩展名
    private static final String CONTEXT_URL_PROPERTY = "domain.contextUrl"; // 上下文URL的系统属性
    private static final String JETTY_WEBRES_PATH_PROPERTY = "JETTY_WEBRES_PATH"; // Jetty Web资源路径的系统属性
    private static final String RESULT_HTML_URL_KEY = "resultHtmlUrl"; // 返回结果中HTML URL的键
    private static final String HTML_NEW_STRING_KEY = "htmlNewString"; // 返回结果中清理后HTML内容的键

    private static final Random RANDOM = new Random(); // 随机数生成器，用于生成唯一文件名

    /**
     * 实现IGPTAction接口的invokeAction方法，处理特定动作。
     *
     * @param action 动作名称
     * @param params 动作相关的参数
     * @return 包含处理结果的Map
     */
    @Override
    public Map<String, String> invokeAction(String action, Map<String, String> params) {
        Map<String, String> result = new HashMap<>(); // 用于存储结果的Map

        // 检查动作是否为GET_QING_HTML
        if ("GET_QING_HTML".equalsIgnoreCase(action)) {
            // 获取htmlResult参数
            String htmlResult = params.get("htmlResult");
            if (htmlResult == null || htmlResult.trim().isEmpty()) {
                // 如果htmlResult缺失或为空，返回错误信息
                result.put("error", "Missing or empty 'htmlResult' parameter.");
                return result;
            }

            // 清理HTML片段，确保包含<!DOCTYPE html>到</html>之间的内容
            String cleanedHtml = cleanHtmlFragment(htmlResult);
            if (cleanedHtml == null) {
                // 如果无法提取有效的HTML片段，返回错误信息
                result.put("error", "Failed to extract valid HTML fragment.");
                return result;
            }

            // 获取当前日期作为目录名
            String directoryName = getCurrentDateString();
            // 构建目标目录路径
            File directory = new File(System.getProperty(JETTY_WEBRES_PATH_PROPERTY), DIRECTORY_PATH + "/" + directoryName);

            // 创建目录（如果不存在）
            if (!directory.exists()) {
                boolean dirsCreated = directory.mkdirs();
                if (!dirsCreated) {
                    // 如果创建目录失败，返回错误信息
                    result.put("error", "Failed to create directory: " + directory.getAbsolutePath());
                    return result;
                }
            }

            // 生成唯一的文件名
            String fileName = generateUniqueFileName();
            // 构建目标文件对象
            File targetFile = new File(directory, fileName + FILE_EXTENSION);

            // 将清理后的HTML内容写入文件
            boolean fileWritten = writeHtmlToFile(cleanedHtml, targetFile);
            if (!fileWritten) {
                // 如果写入文件失败，返回错误信息
                result.put("error", "Failed to write HTML to file: " + targetFile.getAbsolutePath());
                return result;
            }

            // 构建返回的URL，包括上下文URL、目录名、文件名和查询参数
            String contextUrl = System.getProperty(CONTEXT_URL_PROPERTY);
            if (contextUrl == null || contextUrl.trim().isEmpty()) {
                // 如果上下文URL未设置，返回错误信息
                result.put("error", "System property '" + CONTEXT_URL_PROPERTY + "' is not set.");
                return result;
            }

            String resultHtmlUrl = contextUrl + "/" + DIRECTORY_PATH + "/" + directoryName + "/" + fileName + FILE_EXTENSION +
                    "?gaiIframeSize={\"height\":450,\"width\":1000}";

            // 将结果URL和清理后的HTML内容放入返回的Map中
            result.put(RESULT_HTML_URL_KEY, resultHtmlUrl);
            result.put(HTML_NEW_STRING_KEY, cleanedHtml);
        } else {
            // 如果动作不支持，返回错误信息
            result.put("error", "Unsupported action: " + action);
        }

        return result; // 返回处理结果
    }

    /**
     * 清理HTML片段，确保包含<!DOCTYPE html>到</html>之间的内容。
     *
     * @param htmlResult 原始HTML内容
     * @return 清理后的HTML片段，如果无法提取则返回null
     */
    private String cleanHtmlFragment(String htmlResult) {
        if (htmlResult == null) {
            return null;
        }

        // 查找<!DOCTYPE html>的起始位置
        int indexBegin = htmlResult.indexOf("<!DOCTYPE html>");
        if (indexBegin == -1) {
            // 如果没有找到<!DOCTYPE html>，尝试从<html>开始
            indexBegin = htmlResult.indexOf("<html>");
            if (indexBegin == -1) {
                return null; // 无法找到HTML开始标签
            }
            indexBegin += 6; // 跳过"<html>"
        }

        // 查找</html>的结束位置
        int indexEnd = htmlResult.lastIndexOf("</html>");
        if (indexEnd == -1) {
            return null; // 无法找到HTML结束标签
        }

        // 确保开始索引小于结束索引
        if (indexBegin > indexEnd) {
            return null;
        }

        try {
            // 提取并修剪HTML片段
            return htmlResult.substring(indexBegin, indexEnd + 7).trim();
        } catch (StringIndexOutOfBoundsException e) {
            // 日志记录异常（假设有日志系统）
            System.err.println("StringIndexOutOfBoundsException while cleaning HTML: " + e.getMessage());
            return null;
        }
    }

    /**
     * 获取当前日期字符串，格式为yyyy-MM-dd，用作目录名。
     *
     * @return 当前日期字符串
     */
    private String getCurrentDateString() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date());
    }

    /**
     * 生成一个唯一的10位文件名。
     *
     * @return 唯一的文件名字符串
     */
    private String generateUniqueFileName() {
        StringBuilder sb = new StringBuilder(10);
        for (int i = 0; i < 10; i++) {
            // 生成一个随机的ASCII数字字符（'0'-'9'）
            sb.append((char) ('0' + RANDOM.nextInt(10)));
        }
        return sb.toString();
    }

    /**
     * 将HTML内容写入指定的文件。
     *
     * @param htmlContent 要写入的HTML内容
     * @param file        目标文件
     * @return 如果写入成功则返回true，否则返回false
     */
    private boolean writeHtmlToFile(String htmlContent, File file) {
        if (htmlContent == null || file == null) {
            return false;
        }

        FileOutputStream fos = null;
        try {
            // 创建文件输出流
            fos = new FileOutputStream(file);
            // 将HTML内容以UTF-8编码写入文件
            fos.write(htmlContent.getBytes("UTF-8"));
            // 刷新输出流
            fos.flush();
            return true;
        } catch (IOException e) {
            // 日志记录异常（假设有日志系统）
            System.err.println("IOException while writing HTML to file: " + e.getMessage());
            return false;
        } finally {
            // 关闭文件输出流
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    // 忽略关闭流的异常
                }
            }
        }
    }
}
